using System;
using System.Collections.Generic;

namespace WenYu.Runtime
{
    /// <summary>
    /// 栈帧 - 表示函数调用的执行上下文
    /// 
    /// 功能:
    /// - 存储局部变量
    /// - 记录返回地址(指令指针)
    /// - 作用域隔离
    /// 
    /// 对标需求: REQ-05 标准库接口 (预留函数调用支持)
    /// </summary>
    public class StackFrame
    {
        /// <summary>帧的唯一ID(调试用)</summary>
        private static int _nextId = 0;
        public readonly int FrameId = ++_nextId;

        /// <summary>函数/代码块的名称</summary>
        public string Name { get; set; }

        /// <summary>返回地址(下一条指令的索引)</summary>
        public int ReturnAddress { get; set; } = -1;

        /// <summary>局部变量存储</summary>
        private readonly Dictionary<string, Value> _locals = new();

        /// <summary>栈帧的深度(用于调试)</summary>
        public int Depth { get; set; }

        // ===== 构造函数 =====

        /// <summary>
        /// 创建栈帧
        /// </summary>
        /// <param name="name">函数/代码块名称</param>
        /// <param name="depth">栈的深度</param>
        public StackFrame(string name, int depth = 0)
        {
            if (string.IsNullOrEmpty(name))
                throw new ArgumentException("栈帧名称不能为空", nameof(name));
            
            Name = name;
            Depth = depth;
        }

        // ===== 局部变量操作 =====

        /// <summary>
        /// 设置局部变量
        /// </summary>
        public void SetLocal(string varName, Value value)
        {
            if (string.IsNullOrEmpty(varName))
                throw new ArgumentException("变量名不能为空", nameof(varName));
            
            if (value == null)
                throw new ArgumentNullException(nameof(value));

            _locals[varName] = value;
        }

        /// <summary>
        /// 获取局部变量
        /// </summary>
        /// <exception cref="KeyNotFoundException">变量不存在</exception>
        public Value GetLocal(string varName)
        {
            if (!_locals.TryGetValue(varName, out var value))
                throw new KeyNotFoundException($"局部变量未定义: {varName}");

            return value;
        }

        /// <summary>
        /// 检查局部变量是否存在
        /// </summary>
        public bool HasLocal(string varName)
        {
            return _locals.ContainsKey(varName);
        }

        /// <summary>
        /// 获取所有局部变量
        /// </summary>
        public IReadOnlyDictionary<string, Value> GetAllLocals()
        {
            return _locals;
        }

        /// <summary>
        /// 清空所有局部变量
        /// </summary>
        public void ClearLocals()
        {
            _locals.Clear();
        }

        // ===== 信息查询 =====

        /// <summary>
        /// 获取局部变量个数
        /// </summary>
        public int LocalCount => _locals.Count;

        /// <summary>
        /// 获取调试信息
        /// </summary>
        public override string ToString()
        {
            return $"StackFrame#{FrameId}({Name}, RetAddr={ReturnAddress}, Depth={Depth}, Locals={LocalCount})";
        }
    }
}
